#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define THREAD_COUNT 20000

void *add_thread(void *argv)
{
    // 将接收的v参数转换为int指针
    int *p = (int *)argv;

    // 对指向的内存int数据加1,也就是给num加1
    *p = *p + 1;

    return NULL;
}

int main()
{
    pthread_t threads[THREAD_COUNT];

    int num = 0; // 被n个线程进行不断累加的变量

    // 启动20000个线程对num进行累加
    for (int i = 0; i < THREAD_COUNT; i++)
    {
        //多个线程并发访问共享变量 num，每个线程都在读取 num 的值、修改它并存储回去。由于这些操作不是原子的，因此它们可能会被其他线程中断，导致竞态条件。
        //&num:
        //这是传递给 add_thread 函数的参数。
        //由于 add_thread 需要一个 void* 类型的参数，这里传递的是 &num，即 num 变量的地址。
        //如果 num 是一个整数或其他类型的变量，&num 就是该变量的地址。
        //在线程启动时，add_thread 会接收 num 的地址，且可以在函数内部使用这个地址来访问或修改 num 的值。
        pthread_create(&threads[i], NULL, add_thread, &num);
    }
    //竞态条件会导致一些线程的加 1 操作丢失
    // 等待所有线程执行的结果 因为多个线程可能会在同一时刻读取相同的 num 值，修改它，再写回去，造成一些增量操作被“覆盖”掉。
    for (int i = 0; i < THREAD_COUNT; i++)
    {
        pthread_join(threads[i], NULL);
    }
    // 打印累加结果 => 会比20000要小一些
    printf("累加结果：%d \n", num);

    return 0;
}